package org.fixies.spreadsheet;

import org.fixies.spreadsheet.converter.SheetConverter;
import org.fixies.utils.LineSeparator;
import org.fixies.utils.MapIterator;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * シート
 *
 * @author Kawasaki
 */
public class Sheet implements Iterable<Section>, Element {

    private final String bookName_;

    private final String sheetName_;

    private final Map<String, Section> sections_;


    public Sheet(String origin, String sheetName, Map<String, Section> sections) {

        bookName_ = origin;
        sheetName_ = sheetName;
        sections_ = sections;
    }

    /**
     * コンストラクタ
     * 複数のシートを１シートにマージする際に使用する。
     *
     * @param id     ID
     * @param sheets シート群
     */
    public Sheet(String id, Sheet... sheets) {
        // TODO
        throw new UnsupportedOperationException();
//		Map<String, Unit> margedDataSets = new HashMap<String, Unit>();
//		List<Map<String, String>> margedMetadata = new ArrayList<Map<String, String>>();
//		for (Sheet sheet : sheets) {
//			margedDataSets.putAll(sheet.dataSets_);
//			margedMetadata.add(sheet.metadata_);
//		}
//		sheetName_ = id;
//		dataSets_ = Collections.unmodifiableMap(margedDataSets);
//		metadata_ = new MetadataImpl(metadata);
    }

    public Iterator<Section> iterator() {
        return new MapIterator<String, Section>(sections_);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (Section s : sections_.values()) {
            sb.append(s.toString());
            sb.append(LineSeparator.SYSTEM_DEFAULT);
        }
        return sb.toString();
    }

    public String getId() {
        return sheetName_;
    }

    public int size() {
        return sections_.size();
    }

    public Section getSection(String id) {
        return sections_.get(id);
    }


    public Unit getUnit(String id) {
        for (Section e : sections_.values()) {
            Unit unit = e.getUnit(id);
            if (unit != null) return unit;
        }
        throw new SpreadSheetException("no such unit.", bookName_, sheetName_, "" ,id); 
    }

    public List<Unit> getUnits() {
        List<Unit> units = new ArrayList<Unit>();
        for (Section section : sections_.values()) {
            units.addAll(section.getUnits());
        }
        return units;
    }

    public String getOrigin() {
        return "Book=[" + bookName_ + "], Sheet=[" + sheetName_ + "]";
    }

    public <T> T convert(SheetConverter<T> converter) {
        converter.setSheet(this);
        return converter.convert();
    }
}
